<template>
  <el-table :data="tableData" :row-style="showRow" v-bind="$attrs" v-on="$listeners">
    <slot name="selection" />
    <slot name="pre-column" />
    <el-table-column v-for="item in columns" :key="item.key" :label="item.label" :width="item.width" :min-width="item.minWidth" :align="item.align||'center'" :header-align="item.headerAlign">
      <template slot="header">
        <slot>
          <template v-if="item.radio">
            <a v-if="radioSwitch" class="clear" @click="clearRadio">{{ $t('BTN_NAME.CLEAR_AWAY') }}</a>
          </template>
          {{ item.label }}
        </slot>
      </template>
      <template slot-scope="scope">
        <slot :scope="scope" :name="item.key">
          <template v-if="item.expand">
            <span :style="{'padding-left':+scope.row._level*indent + 'px'} " />
            <span v-show="showSperadIcon(scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)">
              <i v-if="scope.row._isLoading" class="el-icon-loading" />
              <i v-else-if="!scope.row._expand" class="el-icon-plus" @click="loadData(scope.row, scope.$index)" />
              <i v-else class="el-icon-minus" />
            </span>
          </template>
          <template v-if="item.checkbox">
            <el-checkbox v-if="scope.row[defaultChildren]&&scope.row[defaultChildren].length>0" v-model="scope.row._select" :style="{'padding-left':+scope.row._level*indent + 'px'} " :indeterminate="scope.row._select && !checkStrictly" @change="handleCheckAllChange(scope.row)" />
            <el-checkbox v-else v-model="scope.row._select" :style="{'padding-left': checkStrictly ? 0 : scope.row._level*indent + 'px'} " @change="handleCheckAllChange(scope.row)" />
          </template>
          <template v-if="item.radio">
            <el-radio v-model="radio" :label="scope.$index" class="table-radio" @change="radioChange(scope.$index,scope.row)">&nbsp;
            </el-radio>
          </template>
          {{ scope.row[item.key] }}
        </slot>
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
import treeToArray, { addAttrs } from "./eval.js";

export default {
  name: 'YhTreeTable',
  props: {
    data: {
      type: Array,
      required: true,
      default: () => []
    },
    columns: {
      type: Array,
      default: () => []
    },
    defaultExpandAll: {
      type: Boolean,
      default: false
    },
    defaultChildren: {
      type: String,
      default: "children"
    },
    indent: {
      type: Number,
      default: 20
    },
    expandTier: {
      type: Number,
      default: 0
    },
    radioSwitch: {
      type: Boolean,
      default: true
    },
    // 是否进行懒加载
    lazy: {
      type: Boolean,
      default: false
    },
    // 在显示复选框的情况下，是否严格的遵循父子不互相关联的做法
    checkStrictly: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      guard: 1,
      radio: -1,
      tableData: []
    };
  },
  computed: {
    // 传入的children字段
    children() {
      return this.defaultChildren;
    }
  },
  // 内部只操作tableData，不操作data
  watch: {
    data: {
      handler(newVal) {
        this.radio = -1;
        this.tableData = newVal.slice(0);
        const data = this.tableData;
        if (data.length === 0) {
          return [];
        }
        // _expand是私有属性，用于组件的内部修改，expand是外部传入对分级按钮的控制
        addAttrs(data, {
          expand: this.defaultExpandAll,
          children: this.defaultChildren,
          expandTier: this.expandTier
        });
        this.tableData = treeToArray(data, this.defaultChildren);
      },
      deep: true
    }
  },
  mounted() {},
  methods: {
    // 点击头部清除按钮清除全部所选项
    clearRadio() {
      this.radio = -1;
      this.$emit("selectData", {}, this.radio);
    },
    // 点击单行按钮触发事件
    radioChange(idx, sels) {
      this.radio = idx;
      this.$emit("selectData", sels, this.radio);
    },
    // addBrother(row, data) {
    //   if (row._parent) {
    //     row._parent.children.push(data)
    //   } else {
    //     this.data.push(data)
    //   }
    // },
    // addChild(row, data) {
    //   if (!row.children) {
    //     this.$set(row, 'children', [])
    //   }
    //   row.children.push(data)
    // },
    // delete(row) {
    //   const {
    //     _index,
    //     _parent
    //   } = row
    //   if (_parent) {
    //     _parent.children.splice(_index, 1)
    //   } else {
    //     this.data.splice(_index, 1)
    //   }
    // },
    // getData() {
    //   return this.tableData
    // },
    // 是否展示当前行判断
    showRow: function({ row }) {
      const parent = row._parent;
      const show = parent ? parent._expand && parent._show : true;
      row._show = show;
      return show
        ? "animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;"
        : "display:none;";
    },
    // 根据children的长度判断是否展示展开的icon
    showSperadIcon(record) {
      return (
        (record[this.children] && record[this.children].length > 0) ||
        (this.lazy && !record._isLeaf)
      );
    },
    // 点击符号展开或收起
    toggleExpanded(trIndex) {
      const record = this.tableData[trIndex];
      const expand = !record._expand;
      if (record._isLoading) return;
      record._expand = expand;
      if (this.lazy && !record._isLoad) {
        this.$set(record, "_isLoading", true);
      }
    },
    // 点击复选框,暴露选择事件
    handleCheckAllChange(row) {
      this.selcetRecursion(row, row._select, this.defaultChildren);
      this.isIndeterminate = row._select;
      const selectData = this.tableData.filter(item => {
        if (item._select) {
          return item;
        }
      });
      this.$emit("selectChange", selectData);
    },
    // 复选框联动处理
    selcetRecursion(row, select, children = "children") {
      if (select) {
        this.$set(row, "_show", true);
        if (!this.checkStrictly) {
          this.$set(row, "_expand", true);
        }
      }
      if (this.checkStrictly) return;
      const sub_item = row[children];
      if (sub_item && sub_item.length > 0) {
        sub_item.map(child => {
          child._select = select;
          this.selcetRecursion(child, select, children);
        });
      }
    },
    // 懒加载触发事件
    loadData(row, index) {
      if (row._isLoad) return;
      this.$emit("loadData", row, node => {
        this.tableData[index].children = node;
        this.tableData[index]._isLoading = false;
        addAttrs(this.tableData);
        if (row[this.children] && row[this.children].length > 0) {
          this.$set(row, "_isLeaf", false);
        } else {
          this.$set(row, "_isLeaf", true);
        }
        this.$set(row, "_isLoad", true);
        this.tableData = treeToArray(this.tableData, this.defaultChildren);
      });
    }
    // updateTreeNode(item) {
    //   return new Promise(resolve => {
    //     const {
    //       _id,
    //       _parent
    //     } = item
    //     const index = _id.split('-').slice(-1)[0] // get last index
    //     if (_parent) {
    //       _parent.children.splice(index, 1, item)
    //       resolve(this.data)
    //     } else {
    //       this.data.splice(index, 1, item)
    //       resolve(this.data)
    //     }
    //   })
    // }
  }
};
</script>

<style>
@keyframes treeTableShow {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@-webkit-keyframes treeTableShow {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.tree-ctrl {
  position: relative;
  cursor: pointer;
  color: #2196f3;
}

.table-radio {
  width: 14px;
}

.clear {
  cursor: pointer;
  color: #2196f3;
}
</style>
